﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace TwitterDotNet.Core
{
    public sealed class Tweet
    {
        public static Tweet CreateStatus(XElement statusdata)
        {
            return new Tweet(statusdata);
        }

        public static Tweet CreateStatus(OauthAccount account, XElement statusdata)
        {
            return new Tweet(account, statusdata);
        }

        public static Tweet CreateStatus(long id, string createdat, string text, string source, long userid)
        {
            return new Tweet(id, createdat, text, source, userid);
        }

        public static Tweet CreateStatus(OauthAccount account, long id, string createdat, string text, string source, long userid)
        {
            return new Tweet(account, id, createdat, text, source, userid);
        }

        internal Tweet(XElement status)
        {
            try
            {
                CreatedAt = status.Element("created_at").Value;
                Id = long.Parse(status.Element("id").Value);
                Text = System.Web.HttpUtility.UrlDecode(status.Element("text").Value);
                Source = status.Element("source").Value;
                User = new User(status.Element("user"));
            }
            catch (Exception e)
            {
                throw new TwitterParseException("XML-data is invalid", e);
            }
        }

        internal Tweet(OauthAccount account, XElement status)
        {
            try
            {
                CreatedAt = status.Element("created_at").Value;
                Id = long.Parse(status.Element("id").Value);
                Text = System.Web.HttpUtility.UrlDecode(status.Element("text").Value);
                Source = status.Element("source").Value;
                User = new User(account, status.Element("user"));
            }
            catch (Exception e)
            {
                throw new TwitterParseException("XML-data is invalid", e);
            }
        }

        internal Tweet(long id, string createdat, string text, string source, long userid)
        {
            Id = id;
            CreatedAt = createdat;
            Text = text;
            User = API.Show(userid);
        }

        internal Tweet(OauthAccount account, long id, string createdat, string text, string source, long userid)
        {
            Id = id;
            CreatedAt = createdat;
            Text = text;
            User = API.Show(account, userid);
        }

        public string CreatedAt { get; private set; }
        public long Id { get; private set; }
        public string Text { get; private set; }
        public string Source { get; private set; }
        public User User { get; private set; }
        public override string ToString() { return Text; }
    }

    public sealed class User
    {
        internal static User CreateUser(XElement userdata)
        {
            return new User(userdata);
        }

        internal static User CreateUser(OauthAccount account, XElement userdata)
        {
            return new User(account, userdata);
        }

        public static User CreateUser(long id, string name, string screenname, string description, Uri profileimageurl, string url, bool isprotected)
        {
            return new User(id, name, screenname, description, profileimageurl, url, isprotected);
        }

        public static User CreateUser(OauthAccount account, long id, string name, string screenname, string description, Uri profileimageurl, string url, bool isprotected)
        {
            return new User(account, id, name, screenname, description, profileimageurl, url, isprotected);
        }

        internal User(XElement userdata)
        {
            try
            {
                Id = long.Parse(userdata.Element("id").Value);
                Name = System.Web.HttpUtility.UrlDecode(userdata.Element("name").Value);
                ScreenName = System.Web.HttpUtility.UrlDecode(userdata.Element("screen_name").Value);
                Location = System.Web.HttpUtility.UrlDecode(userdata.Element("location").Value);
                Description = System.Web.HttpUtility.UrlDecode(userdata.Element("description").Value);
                ProfileIamgeUrl = new Uri(userdata.Element("profile_image_url").Value);
                if (userdata.Element("url").Value != "")
                {
                    Url = userdata.Element("url").Value;
                }
                else
                {
                    Url = null;
                }
                Protected = bool.Parse(userdata.Element("protected").Value);
            }
            catch (Exception e)
            {
                throw new TwitterParseException("XML-data is invalid", e);
            }
        }

        internal User(OauthAccount account, XElement userdata)
        {
            try
            {
                Id = long.Parse(userdata.Element("id").Value);
                Name = System.Web.HttpUtility.UrlDecode(userdata.Element("name").Value);
                ScreenName = System.Web.HttpUtility.UrlDecode(userdata.Element("screen_name").Value);
                Location = System.Web.HttpUtility.UrlDecode(userdata.Element("location").Value);
                Description = System.Web.HttpUtility.UrlDecode(userdata.Element("description").Value);
                ProfileIamgeUrl = new Uri(userdata.Element("profile_image_url").Value);
                if (userdata.Element("url").Value != "")
                {
                    Url = userdata.Element("url").Value;
                }
                else
                {
                    Url = null;
                }
                Protected = bool.Parse(userdata.Element("protected").Value);
            }
            catch (Exception e)
            {
                throw new TwitterParseException("XML-data is invalid", e);
            }
        }

        internal User(long id, string name, string screenname, string description, Uri profileimageurl, string url, bool isprotected)
        {
            Id = id;
            Name = name;
            ScreenName = screenname;
            Description = description;
            ProfileIamgeUrl = profileimageurl;
            Url = url;
            Protected = isprotected;
        }

        internal User(OauthAccount account, long id, string name, string screenname, string description, Uri profileimageurl, string url, bool isprotected)
        {
            Id = id;
            Name = name;
            ScreenName = screenname;
            Description = description;
            ProfileIamgeUrl = profileimageurl;
            Url = url;
            Protected = isprotected;
        }

        public long Id { get; private set; }
        public string Name { get; private set; }
        public string ScreenName { get; private set; }
        public string Location { get; private set; }
        public string Description { get; private set; }
        public Uri ProfileIamgeUrl { get; private set; }
        public string Url { get; private set; }
        public bool Protected { get; private set; }
        public override string ToString() { return this.ScreenName; }
    }
}
